#include <time.h>
#include <unistd.h>
#include <sys/time.h>
#include <iostream>
#include <pthread.h>
#include <sstream>
#include <list>
#include <map>

using namespace std;

#include "prio.h"


void	PrioList::Accumulate(PrioRecord *cr, struct timeval when) 
{
	pthread_mutex_lock(&mutex_);

	PrioRecordMapIter		crmi = crm_m.find(cr->MakeKey());
	PrioRecord	*ncr;
	
	if (crmi == crm_m.end()) {		// not in list new record
		//ncr = new PrioRecord(cr);
		ncr = cr->create();
		// put this new record to the front of the list
		crl_m.push_front(ncr);
		// save the iterator into the 'second' of the map
		crm_m[ncr->MakeKey()] = crl_m.begin();
		ncr->firstUpdate_ = when;
	} else {					// in list already, accumulate
		PrioRecordListIter crli = (*crmi).second;
		ncr = (*crli);
		ncr->update(cr);
		crl_m.erase(crli);
		crl_m.push_front(ncr);
		// iterator is still there and should be valid
		(*crmi).second = crl_m.begin();
		// move this node to the head
	}
	ncr->lastUpdate_ = when;
	pthread_mutex_unlock(&mutex_);
	
}

void	PrioList::MakeListOfFlushItems(PrioRecordList *ulist, struct timeval *since) {
	pthread_mutex_lock(&mutex_);
	int	count = 0;
	int	all = crl_m.size();
	
	for (PrioRecordListIter iter = crl_m.begin(); iter != crl_m.end();) {
		PrioRecord *cr = (*iter++); // increment iterator first as we delete this node
		// TODO: add u_sec
		// add exit when too far back
		if (since == 0 || cr->lastUpdate_.tv_sec < since->tv_sec) {
			PrioRecordMapIter		crmi = crm_m.find(cr->MakeKey());
			if (crmi == crm_m.end()) {
				cerr << "uh oh: record was in list but not in the map!" << endl;
				abort();
			}
			crl_m.erase((*crmi).second); // remove from list
			crm_m.erase(crmi);			// remove from map
			ulist->push_back(cr);	// add to the outgoing list
			count++;
		}
	}
	pthread_mutex_unlock(&mutex_);
}


